<?php

/**
 * Application front controller
 *
 * @package Rapide_Controller
 */
class Rapide_Controller_Front implements Rapide_Controller_Front_Interface
{
	private static $_oInstance;

	private
		$_oRouter,
		$_oDispatcher,
		$_oACL;

	private function __construct()
	{
		$this->_oPluginManager = new Rapide_Controller_Front_Plugin_Manager;
	}

	/**
	 * Get instance of object
	 *
	 * @return Rapide_Controller_Front
	 */
	public static function getInstance()
	{
		if(!self::$_oInstance instanceof self)
			self::$_oInstance = new self;

		return self::$_oInstance;
	}

	/**
	 * Set new router
	 *
	 * @param Rapide_Router_Interface router
	 */
	public function setRouter(Rapide_Router_Interface $oRouter)
	{
		$this->_oRouter = $oRouter;
	}

	/**
	 * Get router
	 *
	 * @return Rapide_Router_Interface
	 */
	public function getRouter()
	{
		if(!$this->_oRouter instanceof Rapide_Router_Interface)
		{
			$this->_oRouter = new Rapide_Router;
		}

		return $this->_oRouter;
	}

	/**
	 * Get dispatcher
	 *
	 * @return Rapide_Dispatcher
	 */
	public function getDispatcher()
	{
		if(!$this->_oDispatcher instanceof Rapide_Dispatcher_Interface)
		{
			$this->_oDispatcher = new Rapide_Dispatcher;
		}

		return $this->_oDispatcher;
	}

	/**
	 * Get ACL object
	 *
	 * @return Rapide_ACL_Interface
	 */
	public function getACL()
	{
		if(!$this->_oACL instanceof Rapide_ACL_Interface)
		{
			$this->_oACL = new Rapide_ACL;
		}

		return $this->_oACL;
	}

	/**
	 * Register execution plugin
	 *
	 * @param Rapide_Controller_Front_Plugin_Interface $oPlugin
	 */
	public function registerPlugin(Rapide_Controller_Front_Plugin_Interface $oPlugin)
	{
		$this->_oPluginManager->register($oPlugin);
	}

	/**
	 * Execute application
	 *
	 */
	public function execute()
	{
		$oToken = $this->getRouter()->execute();
		$oDispatcher = $this->getDispatcher();

		$oToken = $this->_oPluginManager->preDispatchLoop($oToken);

		while($oToken instanceof Rapide_Dispatcher_Token_Interface)
		{
			/* Run preexecution plugins */
			$oToken = $this->_oPluginManager->preExecution($oToken);

			$oNewToken = $oDispatcher->execute($oToken);

			/* Run preexecution plugins for old token */
			$oToken = $this->_oPluginManager->postExecution($oToken);

			$oToken = $oNewToken;
		}

		/* Run postdispatch plugins if returned variable is a token */
		if($oToken instanceof Rapide_Dispatcher_Token_Interface)
			$oToken = $this->_oPluginManager->postDispatchLoop($oToken);
	}
}

?>